package cn.gx.kevin.service.impl;

import java.io.InputStream;
import java.io.OutputStream;
import java.util.*;

import javax.annotation.Resource;

import cn.gx.kevin.Utils.WebConstants;
import cn.gx.kevin.common.user.ILoginUserContext;
import cn.gx.kevin.config.LogInterceptor;
import cn.gx.kevin.dao.IFuncDao;
import cn.gx.kevin.dao.IMenuDao;
import cn.gx.kevin.domain.Func;
import cn.gx.kevin.domain.Menu;
import cn.gx.kevin.domain.Org;
import cn.gx.kevin.service.IFuncService;
import cn.gx.kevin.dao.IBaseDao;
import cn.gx.kevin.service.impl.BaseService;
import cn.gx.kevin.xls.CellSytleUtils;
import cn.gx.kevin.xls.ColumnWidthStyleStrategy;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.excel.metadata.Head;
import com.alibaba.excel.metadata.data.WriteCellData;
import com.alibaba.excel.write.handler.CellWriteHandler;
import com.alibaba.excel.write.handler.RowWriteHandler;
import com.alibaba.excel.write.handler.WriteHandler;
import com.alibaba.excel.write.handler.context.CellWriteHandlerContext;
import com.alibaba.excel.write.handler.context.RowWriteHandlerContext;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
import com.alibaba.excel.write.metadata.holder.WriteTableHolder;
import com.alibaba.excel.write.style.HorizontalCellStyleStrategy;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

/**
 * Generate by Kevin's CodeBuilder
 **/
@Service
public class FuncService extends BaseService<Func, String> implements IFuncService {

    private static final long serialVersionUID = -1L;

    @Resource(name = "loginUserCtx")
    private ILoginUserContext loginUserCtx = null;

    @Autowired
    private IMenuDao menuDao;

    private IFuncDao funcDao;

    @Resource(name = "funcDao")
    @Override
    public void setDao(IBaseDao<Func, String> dao) {
        this.dao = dao;
        funcDao = (IFuncDao) dao;
    }

    @Override
    public List<Func> login(String userId) throws Exception {
        // TODO Auto-generated method stub
        return funcDao.login(userId);
    }

    @Override
    public void insertList(List<Func> list) throws Exception {
        for (Func f : list) {
            Map<String, Object> countParams = new HashMap<String, Object>();
            countParams.put("menuId", f.getMenuId());
            countParams.put("funcCode", f.getFuncCode());
            if (this.count(countParams) == 0) {
                super.insert(f);
            }
        }
    }



    @Override
    public String getOperatorDesp(String controller, String cmd) throws Exception {
        return ((IFuncDao) this.dao).getOperatorDesp(controller, cmd);
    }

    @Override
    public void export(OutputStream outputStream) throws Exception {
        Map<String, Object> params = new HashMap<>();
        LinkedHashMap<String, String> orderMap = new LinkedHashMap<>();
        orderMap.put("f.menu_id", "asc");
        params.put("orderColumn", orderMap);
        List<Func> funcs = this.funcDao.selectParam(params);
        ExcelWriter excelWriter = null;
        HorizontalCellStyleStrategy styleStrategy = CellSytleUtils.getDefaultStyle();
        try {
            excelWriter = EasyExcel.write(outputStream, Func.class).build();
            // 这里注意 如果同一个sheet只要创建一次
            WriteSheet writeSheet = EasyExcel.writerSheet("功能列表").registerWriteHandler(styleStrategy).registerWriteHandler(new ColumnWidthStyleStrategy()).build();
            excelWriter.write(funcs, writeSheet);
        } catch (Exception x) {
            logger.error("", x);
        } finally {
            try {
                excelWriter.finish();
            } catch (Exception x) {
            }
        }
    }

    @Override
    public long importFuncs(MultipartFile xlsFile) throws Exception {
        InputStream inputStream = null;
        List<Menu> allMenus = menuDao.selectParam(new HashMap<>());
        String userId = loginUserCtx.getCurrentUser().getId();

        Map<String, Long> retMap = new HashMap<>();
        retMap.put("ret", 0L);
        try {
            inputStream = xlsFile.getInputStream();
            EasyExcel.read(inputStream, new AnalysisEventListener<LinkedHashMap>() {
                @Override
                public void invoke(LinkedHashMap o, AnalysisContext analysisContext) {
                    String menuText = String.valueOf(o.get(0));
                    String code = String.valueOf(o.get(1));
                    String desp = String.valueOf(o.get(2));
                    String isLog = "是".equals(String.valueOf(o.get(3))) ? "1" : "0";
                    String menuId = null;
                    for (Menu menu : allMenus) {
                        if (StringUtils.isNotEmpty(menu.getController()) && menu.getMenuText().equals(menuText)) {
                            menuId = menu.getId();
                            break;
                        }
                    }
                    if (StringUtils.isNotEmpty(menuId)) {
                        Map<String, Object> countParams = new HashMap<String, Object>();
                        countParams.put("menuId", menuId);
                        countParams.put("funcCode", code);
                        try {
                            if (funcDao.count(countParams) == 0) {
                                Func func = new Func();
                                func.setCreateTime(new Date());
                                func.setCreateUserId(userId);
                                func.setFuncCode(code);
                                func.setFuncDesc(desp);
                                func.setIsLog(isLog);
                                func.setMenuId(menuId);
                                funcDao.insertNotNull(func);
                                Long r = retMap.get("ret") + 1;
                                retMap.put("ret", r);
                            }
                        } catch (Exception x) {
                            logger.error("", x);
                        }
                    }
                }

                @Override
                public void doAfterAllAnalysed(AnalysisContext analysisContext) {
                }
            }).sheet(0).doRead();
            inputStream.close();
            inputStream = null;
        } catch (Exception x) {
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (Exception e) {
                }
            }
            throw x;
        }
        Long coutn = retMap.get("ret");
        return coutn;
    }



}
